---
Title: Kerberos
TitleContent: Kerberos
Description: Protocolo de autenticação segura em redes
Keywords: Autenticação,Rede,Segurança
Author: hrcerq
Template: wiki
Published: 2018-11-06
Modified: 2018-12-08
Tag: Autenticação,Rede,Segurança
---

Kerberos é um protocolo de rede para autenticação segura. O protocolo (e sua implementação de referência) foi desenvolvido no Instituto de Tecnologia de Massachussets (Massachussets Insitute of Technology - MIT). Ele está em sua quinta versão, sendo portanto chamado também de Kerberos V5. Sua especificação está disponível, pela Internet Engineering Task Force - IETF, no documento RFC 4120[^1].

A premissa básica deste protocolo é a de que uma rede não oferece a segurança necessária para trafegar senhas de usuário ou outras informações sensíveis. Embora o uso de firewalls ajude a restringir consideravelmente atividades maliciosas que possam vir a ocorrer, eles só previnem contra ataques de fora da rede, porém nada podem fazer para impedir ataques de dentro.

O serviço Kerberos tem como seu principal objetivo garantir a autenticação segura, isto é, provar que um usuário é quem alega ser antes que este tenha acesso a demais serviços da rede. Opcionalmente, ele também pode provar que um servidor é o servidor que o usuário deseja acessar e não um servidor impostor, que eventualmente possa ser usado para obter informações do usuário indevidamente.

Porém, o Kerberos não tem como objetivo gerenciar contas de usuário ou controlar a autorização. Ou seja, ele não armazena informações de usuário que não suas credenciais, e não define o que um usuário pode fazer. Esse tipo de controle normalmente é feito pelos próprios serviços que serão acessados via Kerberos ou delegados por estes a um serviço de diretório como o LDAP, por exemplo. 

Em outras palavras, se um usuário tenta acessar um serviço de e-mail, por exemplo, via Kerberos, o Kerberos apenas atesta se esse usuário é ele mesmo, mas fica a cargo do serviço de e-mail decidir o que fazer com essa informação, ou seja, decidir o que um usuário autêntico poderá fazer (acessar sua caixa de correio) e o que um usuário impostor poderá fazer (geralmente nada mais que receber uma mensagem de erro).

## Características-chave do Kerberos

* As senhas nunca são transferidas pela rede.
* As senhas de usuário não são armazenadas em sua estação de trabalho. Em vez disso, são descartadas após o uso, durante a autenticação.
* As senhas de usuário armazenadas no servidor do Kerberos são criptografadas.
* O usuário não precisa digitar a senha a cada vez que quiser acessar um serviço. A sessão é persistida por algum tempo, de forma que ele só precisa informar sua senha uma única vez e já poderá acessar vários serviços diferentes sem ter de informá-la de novo a cada acesso. Esta característica é conhecida como Single Sign-On (SSO).
* Credenciais de acesso são centralizadas no Kerberos e não são armazenadas em nenhuma forma nos demais serviços. Isto facilita sua manutenção, pois se o usuário precisar trocar de senha, ela só precisa ser alterada em um serviço. Caso o usuário venha a ser removido, isto só precisa ser feito em um serviço. Ainda, as credenciais só precisam ser protegidas em um serviço.
* Além do usuário, serviços também podem ser obrigados a se autenticar para interagir com o usuário. Esta característica é conhecida como autenticação mútua.
* Uma vez que o processo de autenticação é concluído, o usuário e o serviço podem estabelecer uma comunicação criptografada, se desejado. Para isto, o protocolo suporta o uso de uma chave criptográfica compartilhada entre usuário e serviço para a troca de informações.
* Aplicações que fizerem uso do Kerberos devem ser adaptadas para isso (tanto no software cliente quanto no software servidor). Nem todas as aplicações são integradas ao Kerberos.

## Implementações do Kerberos

Um protocolo apenas define características que o serviço deve oferecer, entretanto não é o serviço em si. Este dependerá das suas implementações, isto é, o software que apresentará as características do protocolo. Algumas das implementações do Kerberos, de código-fonte livre são:

* **MIT Kerberos[^2]:** a primeira implementação, criada no MIT, onde foi criado também o protocolo.
* **Heimdal Kerberos[^3]:** o Heimdal Kerberos foi criado na Suécia, quando o MIT Kerberos ainda era restrito por leis de exportação. O Heimdal não impunha tais restrições (que em 2000 deixaram de existir também para a implementação do MIT).
* **GNU Shishi[^4]:** implementação GNU do protocolo Kerberos V5.
* **Apache Directory[^5]:** além de serviço de LDAP, o Apache Directory também oferece um KDC.
* **Apache Kerby[^6]:** outra implementação do Kerberos mantido pela fundação Apache.

Algumas das implementações de código fechado e proprietário são:

* **Microsoft Active Directory[^7]**
* **Cybersafe TrustBroker[^8]**

## Por que usar o Kerberos

Identificar pessoas é um hábito comum. Cada pessoa tem características únicas, como a aparência física, a voz ou até mesmo o cheiro, que dão aos nossos sentidos a capacidade de distinguir as pessoas umas das outras. E nos damos ao trabalho de identificar pessoas antes de conversar ou interagir com elas porque nossas palavras e ações serão medidas de acordo com os nossos interlocutores. O que diremos a uma pessoa não necessariamente diremos a outra. Em outras palavras, saber com quem nos comunicamos importa para a comunicação.

Às vezes, há situações em que essas características físicas não estão expostas, como em conversas por mensagens de texto, por exemplo. Nesses casos, técnicas como informar um segredo (uma senha) somente conhecido entre os interlocutores pode facilitar a identificação. Porém, quando se tem a complexidade de uma comunicação em rede de computadores, é necessário também utilizar técnicas mais complexas no processo de identificação. 

Informar uma senha em uma rede sem protegê-la dará a possíveis espiões, que monitoram a rede, a possibilidade de tomar conhecimento desta senha e assim poderão se fazer passar por alguém que não são, e com isso obter acesso a recursos que não deveriam ter.

A proposta do protocolo Kerberos é garantir a comunicação segura, mesmo em redes não seguras. E convém lembrar: a premissa de que uma rede de computadores é segura é com frequência a maior falha de segurança dessa rede. Ao considerar uma rede segura, medidas de segurança importantes são deixadas de lado em virtude de uma aparente conveniência.

### Modelos de autenticação

Existem diferentes modelos de autenticação em rede. Alguns são mais seguros do que outros, dependendo do contexto considerado. Para facilitar a compreensão do Kerberos, vamos pensar em três modelos de autenticação (embora existam outros): por asserção, por senha (não segura), e via Kerberos (segura). 

No primeiro cenário (por asserção), o usuário simplesmente informa seu nome e o serviço parte do pressuposto de que ele está sendo honesto. Este modelo sequer pode ser considerado uma autenticação, propriamente, mas oferece a conveniência de não solicitar senha a cada vez que o usuário deseja fazer acesso ao serviço. Neste primeiro cenário, é muito fácil que um usuário finja ser outro e obtenha acesso indevido.

No segundo modelo (senha não segura), o usuário conecta-se ao serviço que deseja acessar, informa sua senha de acesso e então consome o serviço. A cada vez que fizer acesso deverá fornecer sua senha novamente. Embora seja um cenário simples, apresenta uma brecha de segurança: as senhas dos usuários trafegam pela rede sem qualquer tipo de proteção. Assim podem ser facilmente capturadas por alguém que esteja monitorando a rede. 

Se a senha for informada várias vezes, isso aumenta ainda mais o risco de que esta seja interceptada em algum momento. E ainda, se acessar serviços diferentes, sua senha estará armazenada em vários serviços, e para cada um ele terá que informar sua senha (seja esta igual em todos os serviços ou não).

No terceiro cenário, não pode haver conexão direta entre o usuário e o serviço. Ele deve primeiro ser identificado por uma "autoridade da rede", que atesta que ele é quem alega ser, portanto sua primeira conexão será feita com essa autoridade (o Kerberos), que fará uma série de negociações com o usuário e com o serviço (por intermédio do usuário) até que prove a autenticidade do usuário (e opcionalmente do serviço também).

## Conceitos básicos do Kerberos

Antes de explicar o funcionamento deste protocolo, é importante que você se familiarize com alguns conceitos relacionados, que explicarei nas seções a seguir.

### Realm

O protocolo Kerberos trabalha com o conceito de *Realm* (entenda como domínio, território ou extensão): usuários e serviços correspondem a um realm, dentro do qual o serviço Kerberos é considerado como autoridade responsável por autenticá-los. Dessa forma, cada realm deve ter obrigatoriamente um e somente um serviço Kerberos.

Usuários e serviços fora de um realm não podem ser autenticados pelo Kerberos deste realm, mas podem fazer parte de um outro realm. Isto significa que eles podem ser autenticados pelo serviço Kerberos deste outro realm. Também é possível estabelecer uma relação de confiança entre diferentes realms, de forma que o usuário de um realm consiga acessar o serviço de outro realm.

Para fazer parte de um realm, o usuário deve compartilhar um segredo (sua senha) com o Kerberos daquele realm. O nome de um realm é *case-sensitive*, isto é, o realm *GNULINUX.NET.BR* é diferente do realm *gnulinux.net.br*. Por convenção, usa-se caixa alta para nomes de realms. Também é comum que tenham nome igual ao do domínio DNS do qual fazem parte (embora em caixa alta).

### Principal

Usuários, serviços e servidores são catalogados pelo Kerberos de um determinado realm. Cada um deles corresponde a um registro na base de dados do Kerberos. Esses registros são chamados de *Principals*, dentro da terminologia deste serviço. 

De maneira simplista, um principal pode ser entendido como um usuário (pessoal ou impessoal), porém nesta terminologia o termo "usuário" é usado para designar apenas um tipo de principal (aqueles que se autenticam digitando uma senha, e em geral correspondem a uma pessoa).

Porém serviços também são principals e estes não se autenticam digitando uma senha (afinal, quem faria isso?). Ainda assim, cada serviço também compartilha um segredo com o Kerberos, armazenado no servidor que hospeda o serviço. Principals que correspondem a serviços devem ser qualificados pelo servidor onde operam. Assim, o conjunto serviço+servidor forma um principal.

O padrão de nomenclatura para principals que são usuários é formado por uma sequência de componentes e pelo realm, conforme observado a seguir:

```
componente1/componente2/componente3/.../componenteN@REALM
```

Na prática, porém, o uso convencional inclui no máximo dois componentes (nome e opcionalmente uma instância), como a seguir:

```
nome[/instância]@REALM
```

A instância é útil para contextualizar o usuário. Por exemplo, eu poderia criar um usuário normal para mim, e outro também para mim, mas com capacidades administrativas, pois assim não misturaria as funções de usuário normal com as de administrador. Esses usuários seriam:

```
hrcerq@GNULINUX.NET.BR
hrcerq/admin@GNULINUX.NET.BR
```

O padrão de nomenclatura para principals que correspondem a serviços é composto pelo nome do serviço e pelo servidor onde opera, conforme observado a seguir:

```
serviço/servidor@REALM
```

Por exemplo:

```
imap/mail.gnulinux.net.br@GNULINUX.NET.BR
```

É importante que o nome do servidor (no exemplo acima, *mail.gnulinux.net.br*) corresponda exatamente ao nome qualificado, definido para este servidor no DNS.

### Tíquete

O modelo de autenticação do Kerberos não é baseado na troca de senhas. Em vez disso, é baseado na troca de tíquetes. 

> "Mas o que vem a ser um tíquete?"

Um tíquete é um conjunto de informações que o usuário deve apresentar a um serviço quando quiser acessá-lo. As principais informações contidas em um tíquete são:

* principal do usuário;
* principal do serviço;
* endereço de rede a partir de onde o tíquete pode ser usado (pode corresponder a mais de um endereço, ou pode não ser informado, o que significa que qualquer endereço serve);
* horário de emissão do tíquete;
* tempo de validade do tíquete;
* chave de sessão (explicada mais adiante).

O tíquete é criptografado com a senha do serviço para quem ele é destinado. Essa senha é conhecida apelas pelo Kerberos e pelo serviço, logo o próprio usuário que o solicitou não pode ver ou modificar seu conteúdo. Possíveis interceptadores do tíquete também não poderão fazê-lo. 

Quando um serviço recebe o tíquete, ele poderá descriptografá-lo e verificar se o usuário que fez a requisição é o mesmo contido no tíquete, bem como se foi por um endereço de rede autorizado, se foi destinado mesmo a este serviço e se o tíquete ainda é válido.

> "E como esse usuário poderá obter ou produzir esses tíquetes, para então poder acessar os serviços?"

Pense no Kerberos como uma autoridade central, que fiscaliza as tentativas de acesso a serviços, impedindo que impostores sejam considerados legítimos. Então, o usuário deve primeiramente se reportar a essa autoridade, solicitando seu primeiro tíquete, que é conhecido como *Ticket Granting Ticket* (tíquete de concessão de tíquetes) - TGT. O TGT é um tíquete especial, pois servirá para que o usuário obtenha todos os demais tíquetes que precisar.

Cada serviço requer um tíquete diferente. Assim, quando o usuário precisa acessar um serviço, ele vai precisar solicitar um tíquete de acesso daquele serviço. Para fazer esta solicitação, o usuário deverá apresentar o TGT ao Kerberos. Caso o usuário já disponha do tíquete de um determinado serviço, não terá que solicitar novamente. 

Tíquetes são reutilizáveis, mas só até certo ponto. Eles tem um prazo para expirar (em geral uma jornada de trabalho, isto é configurável), o que garante que não possam ter muita utilidade caso sejam interceptados.

### Criptografia

A criptografia é uma característica de grande importância nas comunicações deste protocolo. Afinal, é ela que garante que as mensagens, mesmo sendo interceptadas na rede, não terão serventia alguma. O Kerberos trabalha apenas com criptografia simétrica, o que significa que a mesma chave (senha) usada para criptografar uma mensagem será usada para descriptografá-la. Em outras palavras, o Kerberos trabalha com a ideia de segredo compartilhado. 

A senha do usuário é um segredo compartilhado entre ele e o Kerberos. Assim, o Kerberos pode enviar uma mensagem para o usuário, criptografada com a chave deste usuário e somente ele poderá ler a mensagem. Da mesma forma, a senha de um serviço é um segredo compartilhado entre ele e o Kerberos, que pode gerar um tíquete destinado a esse serviço criptografado com sua chave. Assim, somente o serviço em questão poderá ler o conteúdo do tíquete.

Diferente do Kerberos V4, o Kerberos V5 não determina qual ou quais algoritmos criptográficos podem ser usados. Essa decisão fica a critério das implementações do protocolo. Se por um lado isso dá mais flexibilidade às implementações, por outro pode ocasionar algumas incompatibilidades. Afinal, uma mensagem criptografada com um algoritmo não poderá ser descriptografada com outro. Portanto, para que haja compatibilidade entre diferentes implementações do Kerberos é preciso que estas usem ao menos um algoritmo em comum.

O Kerberos não armazena as senhas de usuário em texto simples no seu banco de dados. Ademais, se uma mesma implementação do Kerberos pode suportar diferentes algoritmos criptográficos, e cada um usa uma chave de tamanho diferente, ocorre que uma mesma senha não poderá ser usada para algoritmos diferentes. 

Portanto, a chave do usuário é na realidade a sua senha transformada por uma função hash chamada **string2key** (texto para chave). Ela converte a senha do usuário para uma chave com o tamanho desejado. Por se tratar de uma função hash, o processo de conversão é irreversível, isto é, não é possível determinar a senha do usuário a partir da chave gerada (a não ser por testes de força bruta).

A cada vez que o usuário substitui sua senha, a função string2key é acionada para gerar a nova chave correspondente. Também, quando o usuário realiza autenticação informando sua senha, a função é chamada para convertê-la antes de ser usada. Esse mencanismo só é aplicável para senhas de usuário. Senhas de serviço são a própria chave, que é gerada automaticamente pelo Kerberos.

Outra novidade do Kerberos V5 foi a inclusão de um mecanismo conhecido como **salt** na função string2key. O salt nada mais é que um texto (o nome do principal) concatenado com a senha antes da aplicação da função hash, conforme a seguinte fórmula:

Chave = string2key(*senha* + *nome do principal*)

Esse mecanismo permite que usuários de mesmo nome, mas instâncias diferentes (ou realms diferentes) tenham chaves diferentes. Como se pode supor, não basta então que diferentes implementações tenham um algoritmo criptográfico em comum para serem compatíveis. Além disso, devem usar ao menos um algoritmo de hash em comum para a função string2key, e devem aplicar o salt da mesma maneira.

As chaves de usuário e de serviço são indexadas por um número de versão. Ou seja, a cada vez que um usuário altera sua senha ou que o administrador de um serviço gera uma nova chave para este serviço, o número da versão desta chave é incrementado. Este número de versão é conhecido como *Key Version Number*, ou mais usualmente **kvno**.

### Key Distribution Center

Vamos falar mais sobre o que é o serviço Kerberos. O serviço que atesta a autenticidade de um usuário é o *Key Distribution Center* (centro de distribuição de chaves) - KDC. Este serviço pode ser entendido como o próprio Kerberos, porque ele é o ponto focal deste protocolo, a peça sem a qual o protocolo não funciona. O KDC é composto por três partes:

* Um serviço de autenticação (*Authentication Service* - AS);
* Um serviço de concessão de tíquetes (*Ticket Granting Service* - TGS);
* Um banco de dados de usuários e serviços (coletivamente chamados de *principals*).

O serviço de autenticação (AS) é o primeiro ponto de contato do usuário com o serviço. É por meio dele que o usuário solicita seu primeiro tíquete (o TGT), que servirá posteriormente para solicitar todos os demais tíquetes que precisar. O AS concederá o TGT aplicando um teste ao usuário que, se bem sucedido, terá comprovado sua autenticidade. Mais detalhes sobre esse teste serão explicados adiante.

O serviço de concessão de tíquetes (TGS) opera com base no TGT recebido pelo usuário. Qualquer usuário que possua um TGT válido poderá solicitar outros tíquetes ao TGS. Assim, o TGS opera de maneira similar a outros serviços da rede, isto é, devem receber um tíquete para que o usuário tenha acesso ao serviço (neste caso, concessão de outros tíquetes).

O banco de dados do Kerberos armazena todos os principals que fazem parte do seu realm. Para cada principal ele guarda também a sua chave atual (e respectivo kvno) e alguns outros metadados do principal, como tempo máximo de validade de um tíquete e prazo de validade do próprio principal, após o qual ele deixará de receber tíquetes. 

### Chave de Sessão

A comunicação segura no protocolo Kerberos parte da premissa de que há um segredo compartilhado entre as partes que se comunicam. Entre o usuário e o KDC, o segredo compartilhado é a chave do usuário. Entre um serviço e o KDC, o segredo é a chave do serviço. Porém, no momento em que o usuário se comunica com o serviço, é preciso que haja também um segredo compartilhado entre eles, ao menos enquanto durar essa comunicação. 

Esse segredo é a chave de sessão (*session key*), ou seja, uma chave que persiste durante uma sessão de trabalho estabelecida. Ela é gerada pelo KDC quando o usuário solicita acesso a algum serviço, e será conhecida pelo usuário e pelo serviço, de forma que poderão estabelecer uma relação de confiança para se comunicar.

### Autenticador

Para que um serviço reconheça um usuário como autêntico, não basta que o tíquete recebido pelo usuário contemple o nome deste usuário e o endereço de rede a partir do qual o tíquete foi enviado, pois um impostor poderia interceptar o tíquete e, ao verificar o usuário e endereço de rede de origem deste tíquete, falsificar suas próximas requisições usando o tíquete interceptado.

Por isso, há que se usar um artifício adicional para garantia de autenticidade: o autenticador. Este artifício é possível graças à chave de sessão, gerada pelo KDC e conhecida somente entre o usuário e o serviço. Um autenticador consiste no nome de usuário e horário de sua criação, criptografados com a chave de sessão. Assim, durante a requisição de acesso a um serviço, o usuário envia não apenas o tíquete mas também o autenticador. O serviço encontrará no tíquete a chave de sessão gerada e com ela poderá descriptografar o autenticador.

Descriptografando o autenticador, o serviço poderá verificar mais uma vez o nome de usuário e o horário de sua criação, que deverá ser tipicamente de no máximo dois minutos atrás (embora esse intervalo seja configurável), para que o usuário seja considerado legítimo. Um autenticador muito antigo poderá indicar que ele foi interceptado e usado indevidamente. Por isso é importante que haja uma sincronia entre as máquinas que fazem parte de um mesmo realm. Caso o horário de alguma máquina não esteja devidamente ajustado, falhas de autenticação provavelmente ocorrerão.

### Replay Cache

Quando se fala em segurança é preciso esgotar as brechas de um sistema e as possibilidades de exploração dessas brechas. No Kerberos, mesmo havendo um autenticador e uma chave de sessão para estabelecer confiança entre usuário e serviço, existe ainda a possibilidade de que tanto o tíquete quanto o autenticador sejam interceptados e usados para falsificar uma identidade dentro do prazo de validade de um autenticador. Embora difícil, não é impossível. 

Por isso, o protocolo Kerberos V5 incluiu também o conceito de *Replay Cache*, isto é, uma área de memória destinada a lembrar os autenticadores recebidos nos últimos 2 minutos (ou o intervalo configurado para aceitação de autenticadores). Assim, se um autenticador for recebido mais de uma vez, somente a primeira será considerada legítima. Isso garante que se um autenticador for interceptado, ele não terá utilidade, pois não poderá ser usado mais de uma vez.

### Credential Cache

As senhas de usuário, transformadas ou não pela função string2key não são nunca armazenadas na estação de trabalho. Mas para implementar a funcionalidade de Single Sign-On, isto é, que o usuário digite sua senha uma única vez durante uma sessão de trabalho, é preciso que de alguma forma suas credenciais sejam persistidas. 

Assim, os tíquetes recebidos e suas chaves de sessões respectivas devem ser armazenadas para o reuso. O protocolo Kerberos determina que deve haver, portanto, um local chamado *Credential Cache*, ou seja, uma área onde esses dados serão persistidos durante a sessão de trabalho. 

Porém o protocolo deixa a critério das implementações onde exatamente ficará este espaço. Algumas implementações usam o próprio sistema de arquivos, outras usam áreas reservadas da memória principal.

## Como o Kerberos funciona

De modo simplificado, podemos separar a comunicação neste protocolo em três etapas: autenticação, obtenção de tíquete e finalmente o acesso à aplicação. Na primeira, há uma comunicação entre o usuário e o serviço de autenticação (AS). Na segunda, há uma comunicação entre o usuário e o serviço de concessão de tíquetes (TGS). Na última, a comunicação é feita entre o usuário e a aplicação que deseja acessar.

Perceba, portanto, que o protagonista de todo o processo é o usuário. O KDC nunca faz comunicação direta com os serviços. Em vez disso, ele entrega mensagens ao usuário, que as repassa ao serviço que vai acessar. Isso será melhor compreendido nas seções a seguir.

Na nomenclatura da especificação do protocolo, as mensagens que serão detalhadas a seguir são chamadas pelos seguintes nomes:

* **KRB_AS_REQ**: mensagem enviada pelo usuário ao serviço de autenticação (AS);
* **KRB_AS_REP**: mensagem devolvida pelo AS ao usuário;
* **KRB_TGS_REQ**: mensagem enviada pelo usuário ao serviço de concessão de tíquetes (TGS);
* **KRB_TGS_REP**: mensagem devolvida pelo TGS ao usuário;
* **KRB_AP_REQ**: mensagem enviada pelo usuário à aplicação;
* **KRB_AP_REP**: mensagem devolvida pela aplicação ao usuário (somente quando a autenticação mútua é requerida).

### Autenticação

**KRB_AS_REQ:**

Em uma rede *kerberizada*, o primeiro passo do usuário é se autenticar com o KDC por meio do serviço de autenticação (AS). O usuário, com seu software cliente do Kerberos conecta-se ao AS para se identificar. Esse primeiro passo é necessário para que ele possa ter acesso a qualquer serviço da rede que faça parte do realm daquele KDC.

Nesse primeiro contato, o usuário envia uma mensagem ao AS. Essa mensagem não contém dados sensíveis, portanto não é criptografada. Ela contempla as informações a seguir:

```
( Pu + Ps + IP + V )
```

Onde **Pu** é o principal do usuário, **Ps** é o principal do serviço a ser acessado, **IP** é uma lista de endereços a partir dos quais o serviço será acessado. Este parâmetro é opcional, e caso omitido significa que os tíquetes recebidos podem ser usados a partir de qualquer endereço. **V** é o tempo de validade máximo desejado para os tíquetes recebidos.

**KRB_AS_REP:**

Ao receber a requisição do usuário, o AS vai varrer a base de dados do KDC à procura dos principals correspondentes ao usuário e ao serviço. Convém lembrar: a base de dados do KDC contempla todos os principals do seu realm, e suas chaves criptográficas. 

Pois bem, o AS verifica se o usuário e o serviço informados constam nessa base de dados, e caso os encontre, prosseguirá com a geração de uma chave de sessão, que será o segredo compartilhado entre o usuário e o serviço de concessão de tíquetes (TGS).

A necessidade deste segredo compartilhado está no fato de que a comunicação seguinte será feita entre o usuário e o TGS. Assim, a chave de sessão é gerada, e em seguida o AS vai gerar também o TGT, que terá as informações a seguir:

```
( Pu + Ptgs + IP + T + V + CStgs )
```

**Pu** é o principal do usuário, **Ptgs** é o principal do serviço de concessão de tíquetes (TGS), **IP** é a lista de endereços de rede que podem usar esse TGT, **T** é o horário (*timestamp*) em que o TGT foi criado, **V** é o prazo de validade desse TGT, e **CStgs** é a chave de sessão que será conhecida apenas entre o usuário e o TGS. 

Como todo tíquete, o TGT é criptografado com a chave do serviço ao qual ele é destinado (neste caso, o TGS). Já que as informações do TGT não devem ser acessíveis ao usuário que fez a requisição, então algumas delas precisam ser transmitidas fora do TGT, de forma que o usuário possa ter acesso. Assim, a resposta do AS para o usuário será:

```
{( Ptgs + T + V + CStgs )}Cpu + {TGT}Ctgs
```

Perceba que a chave de sessão (CStgs) é transmitida ao usuário, em um pacote criptografado com a chave deste usuário (**Cpu**) e será posteriormente transmitida ao TGS por meio do TGT, criptografado com a chave do TGS (**Ctgs**). Isto garante que a chave de sessão não trafegue desprotegida e assim somente o usuário e o TGS conhecerão esta chave.

Ao receber este pacote, o cliente Kerberos do usuário solicitará a senha. Ao digitar a senha, o usuário atesta que é ele mesmo. Essa senha será concatenada ao *salt* e transformada pela função *string2key*. O resultado dessa transformação será a chave do usuário, que vai ser capaz de descriptografar este pacote. O TGT, por sua vez, não será descriptografado pelo usuário (lembre-se: ele é destinado ao TGS). Portanto, o usuário vai apenas transmití-lo ao TGS na etapa de obtenção do tíquete do serviço.

#### Pré-autenticação

Observe que na etapa de requisição (*KRB_AS_REQ*), o usuário envia o principal do usuário, o principal do serviço, uma lista (opcional) de endereços IPs e o tempo máximo de validade desejado para os tíquetes obtidos. Com essas informações, ele consegue obter um pacote criptografado com a senha do usuário e o TGT. Perceba que essas informações enviadas pelo usuário podem ser facilmente obtidas por um impostor.

Se um impostor obtiver um pacote criptografado com a senha do usuário autêntico, poderá usar esse pacote para descobrir a senha do usuário por meio de testes de força bruta. Para evitar que isso ocorra, o protocolo prevê um recurso extra de segurança, chamado de pré-autenticação. Este recurso não é obrigatório, e fica a critério da implementação do protocolo se ele será usado ou não.

Quando este recurso está ativado, um procedimento adicional ocorre entre a requisição do usuário e a resposta do AS. Quando o AS recebe a requisição do usuário, em vez de retornar de imediato a chave de sessão e o TGT, ele envia uma mensagem de volta informando que uma pré-autenticação é necessária.

Feito isso, o cliente Kerberos do usuário que enviou a requisição vai capturar o horário atual e criptografá-lo com a chave do usuário. Portanto o usuário deverá digitar sua senha, que será transformada pela função *string2key*, aplicando o *salt*. Ele vai enviar esse pacote ao AS, que também possui acesso à chave do usuário e portanto deverá ser capaz de descriptografá-lo. 

Caso esse processo ocorra sem erros, a requisição será considerada legítima e então o AS vai retornar a resposta necessária para que o usuário consiga prosseguir com a obtenção do tíquete.

### Obtenção do tíquete

**KRB_TGS_REQ:**

Nesta etapa, o usuário já possui o TGT. Como já foi explicado, o TGT é o tíquete que permite a obtenção de outros tíquetes. O TGT é obtido por meio do AS. Porém todos os demais tíquetes são fornecidos pelo TGS (que pode ser entendido como apenas mais um entre os demais serviços da rede). O usuário ainda precisa de um tíquete para a aplicação que deseja acessar, e o TGS é o serviço que fornecerá esse tíquete.

Convém lembrar que apenas possuir o TGT não basta para que o usuário seja considerado autêntico. Se assim fosse, quando o usuário transmitisse o TGT ao TGS, esse TGT poderia ser interceptado na rede e retransmitido por um impostor. Entretanto, o usuário possui mais uma informação importante: a chave de sessão. Portanto, o usuário constrói um pacote de informações chamado *autenticador*, contemplando seu principal e o horário atual, criptografados com essa chave de sessão:

```
{( Pu + T )}CStgs
```

O TGT deve ser transmitido juntamente com o autenticador ao TGS. Diferentemente do TGT, o autenticador só pode ser usado uma vez. Portanto, se ele for interceptado na rede, não será de nenhuma utilidade.

Dessa forma, a requisição do usuário ao TGS será:

```
( Ps + V + A ) + {TGT}Ctgs
```

Onde **Ps** é o nome do principal do serviço que o usuário deseja acessar (para a qual o TGS vai emitir um tíquete), **V** é o tempo de validade do tíquete gerado e **A** é o autenticador (criptografado com a chave de sessão).

**KRB_TGS_REP:**

Ao receber a requisição do usuário, o TGS vai verificar se o principal da aplicação informado na requisição existe no banco de dados do KDC. Em caso afirmativo, ele vai descriptografar o TGT com sua chave (*Ctgs*) e obter a chave de sessão. Com a chave de sessão, ele vai descriptografar o autenticador. Feito isso, as seguintes condições serão validadas:

* O TGT não está expirado;
* O principal do usuário que enviou a requisição corresponde com o nome de principal de usuário presente no TGT;
* O autenticador enviado não foi utilizado ainda (não está presente no *Replay Cache*) e não expirou;
* Se a lista de IPs informada no TGT não for nula, então o endereço IP do usuário deve corresponder a algum IP dessa lista.

Se todas as condições forem atendidas, o usuário será considerado autêntico pelo TGS, que prosseguirá com a geração de uma resposta. Para isso, ele vai gerar uma nova chave de sessão, que será o segredo compartilhado entre o usuário e o serviço que ele irá acessar. Em seguida, ele vai gerar o tíquete de acesso ao serviço, contemplando as seguintes informações:

```
( Pu + Ps + IP + T + V + CSs )
```

Onde **IP** é a lista (se não nula) de endereços IP que poderão acessar o serviço com esse tíquete, **T** é o instante em que esse tíquete foi gerado, **V** é o tempo de validade do tíquete e **CSs** é a chave de sessão compartilhada entre o usuário e o serviço. Criado o tíquete, o TGS vai formular a resposta para o usuário, contemplando as seguintes informações:

```
{( Ps + T + V + CSs )}CStgs + {Ts}Cs
```

Onde **Ts** é o tíquete destinado ao serviço e **Cs** é a chave criptográfica do serviço. Observe que o primeiro conjunto de informações desta resposta pode ser obtida pelo usuário, pois está criptografada com a chave de sessão usada entre ele e o TGS. Já o tíquete do serviço só poderá ser lido pelo próprio serviço. Portanto, o usuário vai apenas transmití-lo ao serviço na etapa de acesso à aplicação.

### Acesso à aplicação

**KRB_AP_REQ:**

Nesta etapa, o usuário já possui em sua *credential cache* (relembrando: esta é a área em que o usuário guarda os tíquetes obtidos e chaves de sessão) o tíquete do serviço que deseja acessar e a chave de sessão que será compartilhada entre ele e o serviço, ele vai gerar um autenticador para esta nova comunicação com a aplicação. O autenticador será composto pelo principal do usuário e pelo seu horário de criação, criptografados com a nova chave de sessão, gerada para esta comunicação:

```
{( Pu + T)}CSs
```

Em seguida, ele vai gerar a requisição que será enviada para a aplicação:

```
A + {Ts}Cs
```

**A** é o Autenticador, e **Ts** é o tíquete destinado à aplicação, criptografado com a chave desta aplicação (**Cs**). Portanto, a aplicação terá recebido o autenticador e o tíquete. Com isso, ela vai descriptografar o tíquete e dentro dele obter a chave de sessão. Com a chave de sessão, vai descriptografar o autenticador. Tendo feito isso, fará as seguintes verificações:

* O tíquete não está expirado;
* O principal do usuário que enviou a requisição corresponde com o nome de principal de usuário presente no tíquete (Ts);
* O autenticador enviado não foi utilizado ainda (não está presente no *Replay Cache*) e não expirou;
* Se a lista de IPs informada no tíquete não for nula, então o endereço IP do usuário deve corresponder a algum IP dessa lista.

Para os casos em que a autenticação do serviço não é necessária, o protocolo é encerrado com a requisição do usuário para a aplicação. Caso contrário, prosseguirá para a resposta da aplicação, descrita a seguir.

**KRB_AP_REP:**

Em alguns casos, não basta que o usuário seja autenticado para ter acesso ao serviço, mas também que o serviço seja autenticado antes que o usuário faça qualquer requisição. Essa medida pode ser necessária quando se considera o risco de um serviço impostor tentar roubar informações do usuário. Um exemplo disso seria um serviço de impressão que pode ser usado para obter do usuário o documento que este deseja imprimir.

Assim, portanto, nestes casos o usuário informa à aplicação que requer autenticação mútua quando faz a requisição (*KRB_AP_REQ*), e esta deverá oferecer uma resposta que ateste seu conhecimento da chave de sessão (o segredo compartilhado entre o usuário e a aplicação). Portanto, essa resposta será:

```
{( T )}CSs
```

Onde **T** é o mesmo horário presente no autenticador enviado na requisição (*KRB_AP_REQ*). Essa informação é criptografada com a chave de sessão estabelecida para comunicação entre o usuário e aplicação. Se o usuário conseguir descriptografar esse pacote com a chave de sessão estabelecida, o serviço será considerado autêntico.

## Referências

Este artigo foi fortemente inspirado pelos documentos a seguir:

* [Designing an Authentication System: a Dialogue in Four Scenes](https://web.mit.edu/Kerberos/dialogue.html) (Projetando um Sistema de Autenticação: um Diálogo em Quatro Cenas)
* [Kerberos Protocol Tutorial](http://kerberos.org/software/tutorial.html) (Tutorial do Protocolo Kerberos)
* [The MIT Kerberos Administrator's How-to Guide](https://kerberos.org/software/adminkerberos.pdf) (O Guia de Administração do MIT Kerberos)

[^1]: [The Kerberos Network Authentication Service (V5)](https://tools.ietf.org/html/rfc4120) (O Serviço de Autenticação em Rede Kerberos (V5))
[^2]: [MIT Kerberos](http://web.mit.edu/kerberos/)
[^3]: [Heimdal](https://www.h5l.org/)
[^4]: [GNU Shishi](https://www.gnu.org/software/shishi/)
[^5]: [ApacheDS](https://directory.apache.org/apacheds/)
[^6]: [Apache Kerby](https://directory.apache.org/kerby/)
[^7]: [Visão Geral da Autenticação em Kerberos (Windows)](https://docs.microsoft.com/en-us/windows-server/security/kerberos/kerberos-authentication-overview)
[^8]: [CyberSafe TrustBroker](https://cybersafe.com/content/trustbroker-products)

Editor: hrcerq  
email: hrcerq@gnulinux.net.br
